Ruby 日記 12日目: 複数回usingする場合の挙動
次のコードを実行するとどうなりますか
code:gold/ex12/main.rb
class C
def m1(value)
100 + value
end
end
module R1
refine C do
def m1
super 50
end
end
end
module R2
refine C do
def m1
super 100
end
end
end
using R1
using R2
puts C.new.m1
選択肢:
50と表示される
100と表示される
150と表示される
200と表示される
解説:
引数で指定したモジュールで定義された拡張を有効にします。
using R1 によってクラスCのメソッドm1が次のように拡張されたが、
code:rb
def m1
super 50
end
using R2 によってモジュールR1由来のメソッドm1は無効になり、改めてメソッドm1が次のように拡張された、
code:rb
def m1
super 100
end
ということだな
code:sh
# ruby gold/ex12/main.rb
200
よって正解は「200と表示される」
/icons/hr.icon
公式の解説より:
もし、usingを2行書いたとしても1つのメソッドで有効になる再定義は1つだけです。
最後に書いたusingから優先されます。
一方で、using R1に書いた内容はすべて無効になったかというとそういうわけではありません。
次のサンプルコードだとモジュールR2にm2が定義されていなくても呼び出すことが出来ます。
code:gold/ex12/sample.rb
class C
def m1(value)
100 + value
end
def m2(value)
value + ", world"
end
end
module R1
refine C do
def m1
super 50
end
def m2
super "Hello"
end
end
end
module R2
refine C do
def m1
super 100
end
end
end
using R1
using R2
puts C.new.m1 # 200 が表示される
puts C.new.m2 # "Hello, world" が表示される
code:sh
# ruby gold/ex12/sample.rb
200
Hello, world
なるほどね